/*! \file monster.h
	\author Angéline Guignard & Adrien Megueddem
	\copyright Imac Tour Defense
	\language C
	\header Header de monster.c
		La gestion de tous ce qui concerne les monstres du jeu
	\updated 2013-04-22
 */

#ifndef _ITD__MONSTER_H___
#define _ITD__MONSTER_H___

#include <SDL/SDL.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include  <AntTweakBar.h>
#include "../include/modules/coordinates.h"
#include "../include/modules/player.h"
#include "../include/modules/map.h"
#include "../include/modules/sprite.h"
#include "../lib/GM/include/list.h"

/*! \typedef Enum des types des montres
    \brief Structure qui définit les différents types des monstres
    \param baby
    \param low
    \param medium
    \param hard
 */
typedef enum type{
	BABY,
	LOW,
	MEDIUM,
	HARD
}Type;

/*! \typedef struct structure d'un monstre
    \abstract Structure qui définit ce qu'est un monstre
 */
typedef struct monster{
    GLuint *texture;        /*!< GLuint *texture texture du monstre*/
    float width;            /*!< float width largeur du monstre en OpenGL*/
    float height;           /*!< float height hauteur du monstre en OpenGL*/
	int life;               /*!< int life vie du monstre qui décroit*/
    int lifeT;              /*!< int lifeT vie totale du monstre*/
    int resistRocket;       /*!< int resistRocket resistance aux tours de type rocket*/
    int resistLaser;        /*!< int resistLaser resistance aux tours de type laser*/
    int resistHybrid;       /*!< int resistHybrid resistance aux tours de type hybrid*/
    int resistMachineGun;   /*!< int resistMachineGun resistance aux tours de type machineGun*/
	Type type;              /*!< Type type type du monstre*/
	int earn;               /*!< int earn nombre d'argent que rapporte le monstre une fois mort*/
    float speed;            /*!< float speed vitesse du monstre*/
	CoordOpenGL pos;        /*!< CoordOpenGL pos position du monstre en OpenGL*/
    int node;               /*!< int node noeud visé pour avancer*/
    int select;             /*!< int select monstre selectionné ou pas (BOOL)*/
    Sprite sprite;          /*!< Sprite sprite sprite du monstre*/
}Monster;

/*! \fn Monster* createMonster()
    \brief Permet de créer un monstre.
    \result renvoie l'adresse d'un monstre.
*/
Monster* createMonster();

/*! \fn Monster* initMonster(Monster *m, GLuint *textureMonster, Type t, CoordOpenGL in, unsigned int WINDOW_WIDTH, unsigned int WINDOW_HEIGHT, int nbA, int nbS)
    \brief Permet de placer et d'initialiser les caractéristiques d'un monstre.
    \param m adresse du Monstre à initialiser.
    \param textureMonster texture à appliqué sur le monstre.
    \param t détermine le type du monstre.
    \param in position de départ du monstre.
    \param WINDOW_WIDTH taille en largeur de la fenêtre du jeu afin de convertir la taille en OpenGL du monstre.
    \param WINDOW_HEIGHT taille en hauteur de la fenêtre du jeu afin de convertir la taille en OpenGL du monstre.
    \param nbA nombre d'animation d'un sprite
    \param nbS nombre d'états possibles
    \result renvoie l'adresse d'un monstre.
*/
Monster* initMonster(Monster *m, GLuint *textureMonster, Type t, CoordOpenGL in, unsigned int WINDOW_WIDTH, unsigned int WINDOW_HEIGHT, int nbA, int nbS);

/*! \fn int waveMonster(Player *player, Map *map, List *listMonster, GLuint *textureMonster)
    \brief Créer une vague de monstre en fonction de l'avancement du jeu
    \param player prend l'adresse du joueur et l'état de son avancement dans le jeu.
    \param map prend l'adresse de la map
    \param listMonster prend la liste de monstre à modifier.
    \param textureMonster tableau des textures à appliquer aux monstres
    \result renvoie une vague de monstre.
*/
int waveMonster(Player *player, Map *map, List *listMonster, GLuint *textureMonster);

/*! \fn int winWave(List listMonster)
    \brief vérifie si une vague a été exterminé.
    \param listMonster prend la liste de monstre à modifier.
    \result renvoie true or false (1 or 0).
*/
int winWave(List listMonster);

/*! \fn int routeWay(Monster *m, int nbNodes, CoordOpenGL *nodes)
    \brief Permet de mettre à jour la position d'un monstre via les noeuds de la map et l'appel d'updatePosMonster().
    \param monster Monstre à modifier.
    \param nbNodes nombre de noeuds.
    \param nodes tableau de noeuds.
    \result met à jour le noeud vers lequel le monstre avance et appel updatePosMonster().
    \return 1 si le monstre a atteint la sortie, 0 sinon.
*/
int routeWay(Monster *m, int nbNodes, CoordOpenGL *nodes);

/*! \fn void updatePosMonster(Monster *m, CoordOpenGL from, CoordOpenGL to)
    \brief Permet de mettre à jour la position d'un monstre.
    \param monster Monstre à modifier.
    \param from position courante.
    \param to position d'arrivée.
    \result renvoie un monstre après la mise à jour de sa position.
*/
void updatePosMonster(Monster *m, CoordOpenGL from, CoordOpenGL to);

/*! \fn int checkMonster(CoordOpenGL clic, Monster *m)
    \brief Permet de mettre à jour la position d'un monstre.
    \param clic coordonnée cliqué à comparer à un monstre.
    \param m Monstre à comparer au clic.
    \result renvoie 1 si le monstre est cliqué, 0 sinon.
*/
int checkMonster(CoordOpenGL clic, Monster *m);

/*! \fn int getLifeMonster(Monster *m)
    \brief Permet de récupérer la vie d'un monstre (-- / ++).
    \param monster Monstre à modifier.
    \result renvoie la vie d'un monstre.
*/
int getLifeMonster(Monster *m);

/*! \fn void setLifeMonster(Monster *m, int v)
    \brief Permet de modifier la vie d'un monstre (-- / ++).
    \param monster Monstre à modifier.
    \param v dégât reçu par le monstre.
    \result renvoie un monstre après la mise à jour de ses points de vie.
*/
void setLifeMonster(Monster *m, int v);

/*! \fn int getLifeTMonster(Monster *m)
    \brief Permet de récupérer la vie d'un monstre (-- / ++).
    \param monster Monstre à modifier.
    \result renvoie la vie total d'un monstre.
*/
int getLifeTMonster(Monster *m);

/*! \fn void setLifeTMonster(Monster *m, int v)
    \brief Permet de modifier la vie d'un monstre (-- / ++).
    \param monster Monstre à modifier.
    \param v dégât reçu par le monstre.
    \result renvoie un monstre après la mise à jour de ses points de vie.
*/
void setLifeTMonster(Monster *m, int v);

/*! \fn int getResistRocketMonster(Monster *m)
    \brief Permet de récupérer la resistance.
    \param monster Monstre à modifier.
    \result Récupère la valeur voulu.
*/
int getResistRocketMonster(Monster *m);

/*! \fn void setResistRocketMonster(Monster *m, int v)
    \brief Permet de modifier la resistance d'un monstre.
    \param monster Monstre à modifier.
    \param v valeur qui modifie.
    \result modifie la valeur voulu.
*/
void setResistRocketMonster(Monster *m, int v);

/*! \fn int getResistHybridMonster(Monster *m)
    \brief Permet de récupérer la resistance.
    \param monster Monstre à modifier.
    \result Récupère la valeur voulu.
*/
int getResistHybridMonster(Monster *m);

/*! \fn void setResistHybridMonster(Monster *m, int v)
    \brief Permet de modifier la resistance d'un monstre.
    \param monster Monstre à modifier.
    \param v valeur qui modifie.
    \result modifie la valeur voulu.
*/
void setResistHybridMonster(Monster *m, int v);

/*! \fn int getResistLaserMonster(Monster *m)
    \brief Permet de récupérer la resistance.
    \param monster Monstre à modifier.
    \result Récupère la valeur voulu.
*/
int getResistLaserMonster(Monster *m);

/*! \fn void setResistLaserMonster(Monster *m, int v)
    \brief Permet de modifier la resistance d'un monstre.
    \param monster Monstre à modifier.
    \param v valeur qui modifie.
    \result modifie la valeur voulu.
*/
void setResistLaserMonster(Monster *m, int v);

/*! \fn int getResistMachineGunMonster(Monster *m)
    \brief Permet de récupérer la resistance.
    \param monster Monstre à modifier.
    \result Récupère la valeur voulu.
*/
int getResistMachineGunMonster(Monster *m);

/*! \fn void setResistMachineGunMonster(Monster *m, int v)
    \brief Permet de modifier la resistance d'un monstre.
    \param monster Monstre à modifier.
    \param v valeur qui modifie.
    \result modifie la valeur voulu.
*/
void setResistMachineGunMonster(Monster *m, int v);

/*! \fn int getEarnMonster(Monster *m)
    \brief Permet de récupérer l'or que le monstre laisse tomber après sa mort.
    \param monster Monstre.
    \result renvoie un int qui est l'or reçu par le joueur.
*/
int getEarnMonster(Monster *m);

/*! \fn void setEarnMonster(Monster *m, int v)
    \brief Permet de modifier l'or que le monstre laisse tomber après sa mort.
    \param monster Monstre.
    \param v valeur qui modifie.
    \result modifie un int qui est l'or reçu par le joueur.
*/
void setEarnMonster(Monster *m, int v);

/*! \fn List dieMonster(List listMonster, Player *player, TwBar **twMonster)
    \brief Permet de tuer un monstre.
    \param monster Monstre à tuer.
    \param player joueur
    \param twMonster menu du monstre si il existe
    \result efface le monstre et retourne la liste modifié.
*/
List dieMonster(List listMonster, Player *player, TwBar **twMonster);

/*! \fn void drawMonster(Monster *m)
    \brief Permet de dessiner le sprite d'un monstre chargée dans un quad GL.
        Définit le sprite dans le quad GL du monstre et la texture appliqué dessus.
    \param m
    \result dessine le sprite du monstre.
*/
void drawMonster(Monster *m);

/*! \fn void drawLifeMonster(Monster *m)
    \brief Permet de dessiner la vie d'un monstre dans un quad au dessus.
        Définit le quad de la vie d'un monstre.
    \param m Monstre au dessus duquel on dessine la vie.
    \result Dessine la vie du monstre.
*/
void drawLifeMonster(Monster *m);

/*! \fn void drawMonsterSelect(Monster *m)
    \brief Permet de dessiner la selection d'un monstre selectionné.
    \param m Monstre à dessiner.
    \result dessine la selection du monstre
*/
void drawMonsterSelect(Monster *m);

/*! \fn void deleteMonster(Monster *m)
    \brief Permet de supprimer un monstre.
    \param m Monstre à supprimer et free proprement.
    \result supprime le monstre.
*/
void deleteMonster(Monster *m);

#endif